package com.pan.structual.composite.utils;

import com.pan.structual.composite.node.XmlNode;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class XmlUtils {

    private Document xmlDoc;

    public XmlUtils(File xmlFile){
        try {
            xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .parse(xmlFile);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }


    public XmlNode readDoc() {
        Element element = xmlDoc.getDocumentElement();
        XmlNode xmlNode = new XmlNode();
        readDoc(element, xmlNode);
        return xmlNode;
    }



    public List<XmlNode> getAttrs(Element element){

        NamedNodeMap attributes = element.getAttributes();
        List<XmlNode> attrs = new ArrayList<>();
        for (int i = 0; i < attributes.getLength(); i++) {
            Node attr = attributes.item(i);
            String name = attr.getNodeName();
            String value = attr.getNodeValue();
            XmlNode xmlNode = new XmlNode();
            xmlNode.setName(name);
            xmlNode.setValue(value);
            attrs.add(xmlNode);
        }
        return attrs;
    }

    public void readDoc(Element element, XmlNode rootXmlNode) {
        String name = element.getTagName().strip();
        rootXmlNode.setName(name);
        List<XmlNode> attrs = getAttrs(element);
        rootXmlNode.addAttr(attrs);
        if (hasElementChild(element)) {
            List<Element> elementChild = getElementChild(element);
            for (Element childElement : elementChild) {
                XmlNode childXmlNode = new XmlNode();
                rootXmlNode.addChild(childXmlNode);
                readDoc( childElement, childXmlNode);
            }
        } else {
            String value = element.getTextContent().strip();
            rootXmlNode.setValue(value);
        }
    }


    public List<Element> getElementChild(Node node) {
        if (node.getNodeType() != Node.ELEMENT_NODE) {
            throw new RuntimeException("不是element");
        }
        NodeList childNodes = node.getChildNodes();
        List<Element> resultList = new ArrayList<>();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                resultList.add((Element) child);
            }
        }
        return resultList;
    }


    public boolean hasElementChild(Node node) {
        NodeList childNodes = node.getChildNodes();
        if (childNodes.getLength() == 0) {
            return false;
        }
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                return true;
            }
        }
        return false;

    }


    public Document getXmlDoc() {
        return xmlDoc;
    }

    public static void main(String[] args) {
        File file = new File("src/main/java/com/pan/structual/composite/Test.xml");
        XmlUtils xmlUtils = new XmlUtils(file);
        Element e = (Element) xmlUtils.xmlDoc.getDocumentElement().getChildNodes().item(1);
        List<XmlNode> attrs = xmlUtils.getAttrs(e);
        attrs.forEach(System.out::println);
    }
}
